﻿

using HalconDotNet;
using LeaderCCSLaserUI.Common;
using LeaderCCSLaserUI.Data;
using LeaderCCSLaserUI.Data.Extensions;
using LeaderCCSLaserUI.Models;
using LeaderCCSLaserUI.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.Win32;
using MotionRobot.Models;
using MvCamCtrl.NET;
using netDxf;
using netDxf.Entities;
using netDxf.Header;
using netDxf.Tables;
using Newtonsoft.Json;
using NLog;
using Prism.Commands;
using Prism.Regions;
using Prism.Services.Dialogs;
using SQLitePCL;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using ViewROI;
using static System.Formats.Asn1.AsnWriter;
using static System.Windows.Forms.AxHost;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar;
using MessageBox = System.Windows.Forms.MessageBox;
using OpenFileDialog = System.Windows.Forms.OpenFileDialog;

namespace LeaderCCSLaserUI.ViewModels.Dialogs
{
    public class CameraVisionDialogViewModel : DialogViewModel
    {
        #region 变量
        private readonly DrawROI drawROI;
        private int handIndex = 0; private string handDir = string.Empty;
        private Param systemParam;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        string lostfocusColor = "";
        HTuple calc_row, calc_column,calc_angle;
        int CameraHand = 0;
        double mxYJogSpeed = 0, mzJogSpeed = 0, mz1SafePos, mz2SafePos;
        private readonly IHIKCameraService leftCamera;
        private readonly IHIKCameraService rightCamera;
        private readonly IGTSCardService gTSCard;
        private CancellationTokenSource source0, source1;
        private bool isModify = false;
        private bool isClosing = false;
        private bool isGrabActionDone = false;
        private int pointId = 0;
        int FlyTrack = 0;
        #endregion
        #region 属性
        private HImage cameraIamge0;
        public HImage CameraIamge0
        {
            get { return cameraIamge0; }
            set { SetProperty(ref cameraIamge0, value); }
        }
        private bool cameraRepaint0;
        public bool CameraRepaint0
        {
            get { return cameraRepaint0; }
            set { SetProperty(ref cameraRepaint0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }
        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        private bool isSaveToStandardShow;
        public bool IsSaveToStandardShow
        {
            get { return isSaveToStandardShow; }
            set { SetProperty(ref isSaveToStandardShow, value); }
        }
        private bool isBusy;
        public bool IsBusy
        {
            get { return isBusy; }
            set { SetProperty(ref isBusy, value); }
        }
        private int modelKind;
        public int ModelKind
        {
            get { return modelKind; }
            set { SetProperty(ref modelKind, value); }
        }
        private ObservableCollection<int> imageList = new ObservableCollection<int>();
        public ObservableCollection<int> ImageList
        {
            get { return imageList; }
            set { SetProperty(ref imageList, value); }
        }
        private ObservableCollection<int> imagePcsOrderList;
        public ObservableCollection<int> ImagePcsOrderList
        {
            get { return imagePcsOrderList; }
            set { SetProperty(ref imagePcsOrderList, value); }
        }
        private double cameraExposureTime;
        public double CameraExposureTime
        {
            get { return cameraExposureTime; }
            set { SetProperty(ref cameraExposureTime, value); }
        }
        private ObservableCollection<FlyPointDisp> pointList1 = new ObservableCollection<FlyPointDisp>();
        public ObservableCollection<FlyPointDisp> PointList1
        {
            get { return pointList1; }
            set { SetProperty(ref pointList1, value); }
        }
        private ObservableCollection<FlyPointDisp> pointList2 = new ObservableCollection<FlyPointDisp>();
        public ObservableCollection<FlyPointDisp> PointList2
        {
            get { return pointList2; }
            set { SetProperty(ref pointList2, value); }
        }
        private ObservableCollection<FlyPointDisp> pointList3 = new ObservableCollection<FlyPointDisp>();
        public ObservableCollection<FlyPointDisp> PointList3
        {
            get { return pointList3; }
            set { SetProperty(ref pointList3, value); }
        }
        private int imagePcsOrderSelectedIndex;
        public int ImagePcsOrderSelectedIndex
        {
            get { return imagePcsOrderSelectedIndex; }
            set { SetProperty(ref imagePcsOrderSelectedIndex, value); }
        }
        private bool isDrawing;
        public bool IsDrawing
        {
            get { return isDrawing; }
            set { SetProperty(ref isDrawing, value); }
        }

        private ObservableCollection<VisionProgramDisp> scriptList = new ObservableCollection<VisionProgramDisp>();
        public ObservableCollection<VisionProgramDisp> ScriptList
        {
            get { return scriptList; }
            set { SetProperty(ref scriptList, value); }
        }
        private int scriptListSelectedIndex;
        public int ScriptListSelectedIndex
        {
            get { return scriptListSelectedIndex; }
            set { SetProperty(ref scriptListSelectedIndex, value); }
        }
        private bool isFlyGrab;
        public bool IsFlyGrab
        {
            get { return isFlyGrab; }
            set { SetProperty(ref isFlyGrab, value); }
        }
        private ObservableCollection<int> flyTrackList = new ObservableCollection<int>();
        public ObservableCollection<int> FlyTrackList
        {
            get { return flyTrackList; }
            set { SetProperty(ref flyTrackList, value); }
        }
        private ObservableCollection<FlyTrackDisp> flyTrackList2 = new ObservableCollection<FlyTrackDisp>();
        public ObservableCollection<FlyTrackDisp> FlyTrackList2
        {
            get { return flyTrackList2; }
            set { SetProperty(ref flyTrackList2, value); }
        }
        #endregion
        #region 方法绑定
        private DelegateCommand<object> cameraOperateCommand;
        public DelegateCommand<object> CameraOperateCommand =>
            cameraOperateCommand ?? (cameraOperateCommand = new DelegateCommand<object>(ExecuteCameraOperateCommand));        
        private DelegateCommand<object> createRec1RegionCommand;
        public DelegateCommand<object> CreateRec1RegionCommand =>
            createRec1RegionCommand ?? (createRec1RegionCommand = new DelegateCommand<object>(ExecuteCreateRec1RegionCommand));
        private DelegateCommand<object> calcCommand;
        public DelegateCommand<object> CalcCommand =>
            calcCommand ?? (calcCommand = new DelegateCommand<object>(ExecuteCalcCommand));
        private DelegateCommand<object> saveToStandardCommand;
        public DelegateCommand<object> SaveToStandardCommand =>
            saveToStandardCommand ?? (saveToStandardCommand = new DelegateCommand<object>(ExecuteSaveToStandardCommand));

        private DelegateCommand grabImageCommand;
        public DelegateCommand GrabImageCommand =>
            grabImageCommand ?? (grabImageCommand = new DelegateCommand(ExecuteGrabImageCommand));
        private DelegateCommand<object> flyGrabImageCommand;
        public DelegateCommand<object> FlyGrabImageCommand =>
            flyGrabImageCommand ?? (flyGrabImageCommand = new DelegateCommand<object>(ExecuteFlyGrabImageCommand));

        private DelegateCommand<object> openImageCommand;
        public DelegateCommand<object> OpenImageCommand =>
            openImageCommand ?? (openImageCommand = new DelegateCommand<object>(ExecuteOpenImageCommand));
        
        private DelegateCommand<object> selectModelKindCommand;
        public DelegateCommand<object> SelectModelKindCommand =>
            selectModelKindCommand ?? (selectModelKindCommand = new DelegateCommand<object>(ExecuteSelectModelKindCommand));
        private DelegateCommand<object> createTargetPosCommand;
        public DelegateCommand<object> CreateTargetPosCommand =>
            createTargetPosCommand ?? (createTargetPosCommand = new DelegateCommand<object>(ExecuteCreateTargetPosCommand));
        private DelegateCommand<object> imageListSelectCommand;
        public DelegateCommand<object> ImageListSelectCommand =>
            imageListSelectCommand ?? (imageListSelectCommand = new DelegateCommand<object>(ExecuteImageListSelectCommand));
        private DelegateCommand<object> liveGrabCommand;
        public DelegateCommand<object> LiveGrabCommand =>
            liveGrabCommand ?? (liveGrabCommand = new DelegateCommand<object>(ExecuteLiveGrabCommand));
        private DelegateCommand<object> pointList1RowEditEndingCommand;
        public DelegateCommand<object> PointList1RowEditEndingCommand =>
            pointList1RowEditEndingCommand ?? (pointList1RowEditEndingCommand = new DelegateCommand<object>(ExecutePointList1RowEditEndingCommand));
        private DelegateCommand<object> pointList1TeachPosCommand;
        public DelegateCommand<object> PointList1TeachPosCommand =>
            pointList1TeachPosCommand ?? (pointList1TeachPosCommand = new DelegateCommand<object>(ExecutePointList1TeachPosCommand));
        private DelegateCommand<object> pointList1JumpPosCommand;
        public DelegateCommand<object> PointList1JumpPosCommand =>
            pointList1JumpPosCommand ?? (pointList1JumpPosCommand = new DelegateCommand<object>(ExecutePointList1JumpPosCommand));
        private DelegateCommand<object> pointList1GoPosCommand;
        public DelegateCommand<object> PointList1GoPosCommand =>
            pointList1GoPosCommand ?? (pointList1GoPosCommand = new DelegateCommand<object>(ExecutePointList1GoPosCommand));
        private DelegateCommand saveFlyImageCommand;
        public DelegateCommand SaveFlyImageCommand =>
            saveFlyImageCommand ?? (saveFlyImageCommand = new DelegateCommand(ExecuteSaveFlyImageCommand));
        private DelegateCommand loadFlyImageCommand;
        public DelegateCommand LoadFlyImageCommand =>
            loadFlyImageCommand ?? (loadFlyImageCommand = new DelegateCommand(ExecuteLoadFlyImageCommand));
        private DelegateCommand<object> selectTrackCommand;
        public DelegateCommand<object> SelectTrackCommand =>
            selectTrackCommand ?? (selectTrackCommand = new DelegateCommand<object>(ExecuteSelectTrackCommand));
        private DelegateCommand<object> imageList2SelectCommand;
        public DelegateCommand<object> ImageList2SelectCommand =>
            imageList2SelectCommand ?? (imageList2SelectCommand = new DelegateCommand<object>(ExecuteImageList2SelectCommand));
        private DelegateCommand<object> selectDataGridFlyTrackCommand;
        public DelegateCommand<object> SelectDataGridFlyTrackCommand =>
            selectDataGridFlyTrackCommand ?? (selectDataGridFlyTrackCommand = new DelegateCommand<object>(ExecuteSelectDataGridFlyTrackCommand));
        private DelegateCommand<object> scriptListSelectCommand;
        public DelegateCommand<object> ScriptListSelectCommand =>
            scriptListSelectCommand ?? (scriptListSelectCommand = new DelegateCommand<object>(ExecuteScriptListSelectCommand));
        private DelegateCommand<object> textBoxLostFocusCommand;
        public DelegateCommand<object> TextBoxLostFocusCommand =>
            textBoxLostFocusCommand ?? (textBoxLostFocusCommand = new DelegateCommand<object>(ExecuteTextBoxLostFocusCommand));
        private DelegateCommand<object> isFlyGrabCommand;
        public DelegateCommand<object> IsFlyGrabCommand =>
            isFlyGrabCommand ?? (isFlyGrabCommand = new DelegateCommand<object>(ExecuteIsFlyGrabCommand));
        private DelegateCommand refreshCommand;
        public DelegateCommand RefreshCommand =>
            refreshCommand ?? (refreshCommand = new DelegateCommand(ExecuteRefreshCommand));

        void ExecuteRefreshCommand()
        {
            try
            {
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
                if (point != null)
                {
                    var vision = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                    if (vision != null)
                    {
                        ModelKind = vision.ModelKind;
                        FlyTrack = vision.Track;                        
                        ChangeImagePcsOrderList(vision.Hand, vision.Track, vision.ImageKind);
                        ImagePcsOrderSelectedIndex = vision.ImagePcsOrder;
                        IsFlyGrab = vision.ImageKind != 0;
                        LoadImage(vision.Track, vision.ImageKind, vision.ImagePcsOrder);
                        if (CameraIamge0 != null)
                        {
                            CameraAppendHObject0 = null;
                            HOperatorSet.GenRectangle1(out var rec, vision.Rec1Row1, vision.Rec1Column1, vision.Rec1Row2, vision.Rec1Column2);
                            CameraGCStyle0 = new Tuple<string, object>("Color", "magenta");
                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                            CameraAppendHObject0 = rec;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteIsFlyGrabCommand(object obj)
        {
            if (obj is bool v1)
            {
                if (!v1)
                {
                    ChangeImagePcsOrderList(CameraHand, 0, 0);
                }
            }
        }
        void ExecuteTextBoxLostFocusCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "CameraExposureTime":
                    try
                    {
                        using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                        var _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "CameraExposureTime" && m.Hand == handIndex);
                        if (_mParam != null)
                        {
                            _mParam.Value = CameraExposureTime.ToString();
                            mdb.SaveChanges();
                        }
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    break;
            }
        }
        void ExecuteScriptListSelectCommand(object obj)
        {
            if (obj is VisionProgramDisp vdisp)
            {                
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
                if (point != null)
                {
                    var vision = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                    if (vision != null)
                    {
                        vision.ScriptFileName = $"{vdisp.Id}_{vdisp.Name}";
                        mdb.SaveChanges();
                    }
                }
            }
        }
        void ExecuteSelectDataGridFlyTrackCommand(object obj)
        {
            LoadFlyPoint(int.Parse(obj.ToString()) - 1);
        }

        void ExecuteImageList2SelectCommand(object obj)
        {
            if (obj is int _index)
            {
                LoadImage(FlyTrack, IsFlyGrab ? 1 : 0, _index);
            }
        }
        void ExecuteSelectTrackCommand(object obj)
        {
            if (int.TryParse(obj.ToString(), out var v1))
            {
                FlyTrack = v1 - 1;
                FlyTrackList2[v1 - 1].IsChecked = true;
            }
            ChangeImagePcsOrderList(CameraHand, FlyTrack, 1);
        }
        void ExecuteLoadFlyImageCommand()
        {
            using (var fbd = new FolderBrowserDialog())
            {
                System.Windows.Forms.DialogResult result = fbd.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
                {
                    try
                    {
                        gTSCard.ImageList.Clear();
                        ImageList.Clear();
                        int imageCount = 0;
                        string[] fileNames = Directory.GetFiles(fbd.SelectedPath, "*.jpg", SearchOption.TopDirectoryOnly);
                        for (int m = 0; m < 2; m++)
                        {
                            for (int k = 0; k < 2; k++)
                            {
                                for (int i = 0; i < 6; i++)
                                {
                                    for (int j = 0; j < 20; j++)
                                    {
                                        var _file = fileNames.FirstOrDefault(file => file.Contains($"{m}_{k}_{i}_{j}"));
                                        if (_file != null)
                                        {
                                            HOperatorSet.ReadImage(out var mimage1, _file);
                                            gTSCard.ImageList.Add(new FlyImage
                                            {
                                                Kind = m,
                                                CameraHand = k,
                                                Track = i,
                                                ImagePcsOrder = j,
                                                MImage = mimage1
                                            });
                                            ImageList.Add(imageCount + 1);
                                            imageCount++;
                                        }
                                    }
                                }
                            }
                        }


                        MessageBox.Show($"加载了{imageCount}张图片", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
        void ExecuteSaveFlyImageCommand()
        {
            using (var fbd = new FolderBrowserDialog())
            {
                System.Windows.Forms.DialogResult result = fbd.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
                {
                    try
                    {
                        foreach (var item in gTSCard.ImageList)
                        {
                            HOperatorSet.WriteImage(item.MImage, "jpeg", 0, Path.Combine(fbd.SelectedPath, $"{item.Kind}_{item.CameraHand}_{item.Track}_{item.ImagePcsOrder}.jpg"));
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
        async void ExecutePointList1GoPosCommand(object obj)
        {
            if (obj is FlyPointDisp flypoint)
            {
                if (MessageBox.Show("确认Go运动吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    IsBusy = true;
                    AxisParm axisX, axisY, axisZ;
                    switch (handIndex)
                    {
                        case 0:
                            axisX = gTSCard.A1;
                            axisY = gTSCard.A2;
                            axisZ = gTSCard.A3;
                            break;
                        case 1:
                        default:
                            axisX = gTSCard.A5;
                            axisY = gTSCard.A6;
                            axisZ = gTSCard.A7;
                            break;
                    }
                    GTSCard.ServoOn(axisX);//X
                    GTSCard.ServoOn(axisY);//Y
                    GTSCard.ServoOn(axisZ);//Z
                    GTSCard.AxisPosSet(axisX, GTSCard.GetEnc(axisX));
                    GTSCard.AxisPosSet(axisY, GTSCard.GetEnc(axisY));
                    GTSCard.AxisPosSet(axisZ, GTSCard.GetEnc(axisZ));
                    source1 = new CancellationTokenSource();
                    CancellationToken token = source1.Token;
                    await Task.Run(() => GoAction(token, flypoint.X, flypoint.Y, flypoint.Z, axisX, axisY, axisZ), token).ContinueWith(t => { IsBusy = false; });
                }
            }
        }
        async void ExecutePointList1JumpPosCommand(object obj)
        {
            if (obj is FlyPointDisp flypoint)
            {
                if (MessageBox.Show("确认Jump运动吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    IsBusy = true;
                    AxisParm axisX, axisY, axisZ;
                    double zSafePos;
                    switch (handIndex)
                    {
                        case 0:
                            axisX = gTSCard.A1;
                            axisY = gTSCard.A2;
                            axisZ = gTSCard.A3;
                            zSafePos = mz1SafePos;
                            break;
                        case 1:
                        default:
                            axisX = gTSCard.A5;
                            axisY = gTSCard.A6;
                            axisZ = gTSCard.A7;
                            zSafePos = mz2SafePos;
                            break;
                    }
                    GTSCard.ServoOn(axisX);//X
                    GTSCard.ServoOn(axisY);//Y
                    GTSCard.ServoOn(axisZ);//Z
                    GTSCard.AxisPosSet(axisX, GTSCard.GetEnc(axisX));
                    GTSCard.AxisPosSet(axisY, GTSCard.GetEnc(axisY));
                    GTSCard.AxisPosSet(axisZ, GTSCard.GetEnc(axisZ));
                    source1 = new CancellationTokenSource();
                    CancellationToken token = source1.Token;
                    await Task.Run(() => JumpAction(token, flypoint.X, flypoint.Y, flypoint.Z, axisX, axisY, axisZ, zSafePos), token).ContinueWith(t => { IsBusy = false; });
                }
            }
        }
        void ExecutePointList1TeachPosCommand(object obj)
        {
            if (obj is FlyPointDisp flypoint)
            {
                if (MessageBox.Show("确认示教吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    switch (handIndex)
                    {
                        case 0:
                            flypoint.X = Math.Round(GTSCard.GetEnc(gTSCard.A1), 3);
                            flypoint.Y = Math.Round(GTSCard.GetEnc(gTSCard.A2), 3);
                            flypoint.Z = Math.Round(GTSCard.GetEnc(gTSCard.A3), 3);
                            break;
                        case 1:
                        default:
                            flypoint.X = Math.Round(GTSCard.GetEnc(gTSCard.A5), 3);
                            flypoint.Y = Math.Round(GTSCard.GetEnc(gTSCard.A6), 3);
                            flypoint.Z = Math.Round(GTSCard.GetEnc(gTSCard.A7), 3);
                            break;
                    }
                    using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                    var point = mdb.FlyGrabPoints.FirstOrDefault(p => p.Id == flypoint.Id);
                    if (point != null)
                    {
                        point.X = flypoint.X;
                        point.Y = flypoint.Y;
                        point.Z = flypoint.Z;
                        mdb.SaveChanges();
                    }
                }
            }
        }
        void ExecutePointList1RowEditEndingCommand(object obj)
        {
            if (obj is FlyPointDisp flypoint)
            {
                try
                {
                    using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                    var point = mdb.FlyGrabPoints.FirstOrDefault(p => p.Id == flypoint.Id);
                    if (point != null)
                    {
                        point.X = flypoint.X;
                        point.Y = flypoint.Y;
                        point.Z = flypoint.Z;
                        point.UseLight1 = flypoint.UseLight1;
                        point.UseLight2 = flypoint.UseLight2;
                        mdb.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex);
                }
            }
        }
        void ExecuteLiveGrabCommand(object obj)
        {
            if ((bool)obj)
            {
                source1 = new CancellationTokenSource();
                CancellationToken token = source1.Token;
                Task.Run(() => ContinueGrab(token), token);
                IsBusy = true;
            }
            else
            {
                if (source1 != null)
                {
                    source1.Cancel();
                }
                IsBusy = false;
            }
        }
        void ExecuteImageListSelectCommand(object obj)
        {
            if (obj is int _index)
            {
                try
                {
                    CameraIamge0 = new HImage(gTSCard.ImageList.ToArray()[_index - 1].MImage.CopyObj(1, -1));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                
            }
        }
        void ExecuteCreateTargetPosCommand(object obj)
        {
            if (CameraIamge0 != null)
            {
                if (MessageBox.Show($"确认要画焊接位置吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {                    
                    try
                    {
                        CameraAppendHObject0 = null;
                        IsDrawing = true;
                        var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_CIRCLE);
                        IsDrawing = false;
                        if (!isClosing)
                        {
                            var region = roi.getRegion();
                            HOperatorSet.RegionFeatures(region, "row", out var _row);
                            HOperatorSet.RegionFeatures(region, "column", out var _column);
                            HOperatorSet.GenCrossContourXld(out var cross, _row, _column, 16, 0);
                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                            CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                            CameraAppendHObject0 = cross;
                            using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                            var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
                            if (point != null)
                            {
                                var visionPcs = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                                if (visionPcs != null)
                                {
                                    visionPcs.Target_X = Math.Round(_row.D, 3);
                                    visionPcs.Target_Y = Math.Round(_column.D, 3);
                                    mdb.SaveChanges();
                                }
                            }
                            region.Dispose();
                        }
             
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
        void ExecuteSelectModelKindCommand(object obj)
        {
            ModelKind = int.Parse(obj.ToString());

            using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
            var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
            if (point != null)
            {
                var vision = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                if (vision != null)
                {
                    vision.ModelKind = ModelKind;
                    mdb.SaveChanges();
                }
            }

        }        
        void ExecuteOpenImageCommand(object obj)
        {
            //int index = int.Parse(obj.ToString());
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Image Files|*.png;*.bmp;*.jpg;*.tif";
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                HOperatorSet.ReadImage(out var mimage1, openFileDialog.FileName);
                CameraIamge0 = new HImage(mimage1);
                IsSaveToStandardShow = false;
            }
        }
        async void ExecuteGrabImageCommand()
        {
            IHIKCameraService cameraService = handIndex == 0 ? leftCamera : rightCamera;
            IsBusy = true;
            cameraService.ImageQueue.Clear();
            cameraService.SetTriggerMode(0);
            cameraService.SetExposureTime((float)CameraExposureTime);
            cameraService.StartGrabe();
            await Task.Run(() => {
                int mIndex = 0;
                while (mIndex < 1)
                {
                    HObject? hObj;
                    if (cameraService.ImageQueue.TryPeek(out hObj))
                    {
                        cameraService.ImageQueue.TryDequeue(out hObj);
                        CameraIamge0 = new HImage(hObj);
                        mIndex++;
                    }
                }
            }).ContinueWith(t => { cameraService.StopGrabe(); IsBusy = false; });
        }
        async void ExecuteFlyGrabImageCommand(object obj)
        {
            if (MessageBox.Show("确认要飞拍吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
            {
                
                ImageList.Clear();
                gTSCard.ImageList.Clear();
                IsBusy = true;
                source0 = new CancellationTokenSource();
                CancellationToken token = source0.Token;
                await Task.Run(() =>
                {
                    ScanGrabImageAction(token);
                }, token).ContinueWith(t => { IsBusy = false;});
                
            }
        }       
        void ExecuteSaveToStandardCommand(object obj)
        {
            using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
            var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
            if (point != null)
            {
                var visionPcs = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                if (visionPcs != null)
                {
                    visionPcs.ST_X = Math.Round(calc_row.D, 3);
                    visionPcs.ST_Y = Math.Round(calc_column.D, 3);
                    visionPcs.ST_Angle = Math.Round(calc_angle.D, 3);

                    mdb.SaveChanges();

                    MessageBox.Show($"点位{visionPcs.Name}基准更新完成", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            
        }
        void ExecuteCalcCommand(object obj)
        {
            using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
            var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
            if (point != null)
            {
                var visionPcs = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                if (visionPcs != null)
                {
                    var flyimg = gTSCard.ImageList.FirstOrDefault(fly => fly.Track == visionPcs.Track && fly.Kind == visionPcs.ImageKind && fly.ImagePcsOrder == visionPcs.ImagePcsOrder && fly.CameraHand == visionPcs.CameraHand);
                    if (flyimg != null)
                    {
                        try
                        {

                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");

                            HOperatorSet.CropPart(flyimg.MImage, out var imagePart, visionPcs.Rec1Row1, visionPcs.Rec1Column1, visionPcs.Rec1Column2 - visionPcs.Rec1Column1, visionPcs.Rec1Row2 - visionPcs.Rec1Row1);

                            HTuple r_row = new HTuple(0), r_column = new HTuple(0), r_angle = new HTuple(0), result = new HTuple(0);
                            VisionAction(visionPcs.ScriptFileName, imagePart, visionPcs.ModelKind, out r_row, out r_column, out r_angle, out result);

                            CameraIamge0 = new HImage(imagePart);
                            CameraGCStyle0 = new Tuple<string, object>("Color", "yellow");

                            if (result.I == 1 && r_row.TupleLength() > 0 && r_column.TupleLength() > 0 && r_angle.TupleLength() > 0)
                            {
                                calc_row = r_row;
                                calc_column = r_column;
                                calc_angle = r_angle;
                                HOperatorSet.TupleDeg(r_angle, out var _angle);
                                CameraAppendHMessage0 = new HMsgEntry($"{_angle.D:f2}°", 10, 10, _Size: 16, _coordSystem: "window");
                                HOperatorSet.GenCrossContourXld(out var cross1, r_row, r_column, 24, 0);
                                CameraGCStyle0 = new Tuple<string, object>("Color", "red");
                                CameraAppendHObject0 = cross1;

                                HOperatorSet.VectorAngleToRigid(visionPcs.ST_X, visionPcs.ST_Y, visionPcs.ST_Angle, r_row, r_column, r_angle, out var homMat2D);
                                HOperatorSet.AffineTransPoint2d(homMat2D, visionPcs.Target_X, visionPcs.Target_Y, out var qx, out var qy);
                                HOperatorSet.GenCrossContourXld(out var cross0, qx, qy, 24, 0);
                                CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                                CameraAppendHObject0 = cross0;

                                IsSaveToStandardShow = true;
                            }
                            else
                            {
                                CameraAppendHMessage0 = new HMsgEntry($"NG", 40, 40, "orange red", "window", "box", "false", 24, "mono", "true", "false");
                                IsSaveToStandardShow = false;
                            }
                        }
                        catch (Exception ex)
                        {
                            IsSaveToStandardShow = false;
                            MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show($"点位\"{visionPcs.Name}\"无图像", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            
        }
        void ExecuteCreateRec1RegionCommand(object obj)
        {
            if (CameraIamge0 != null)
            {
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
                if (point != null)
                {
                    var visionPcs = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                    if (visionPcs != null)
                    {
                        if (MessageBox.Show($"确认要画\"{visionPcs.Name}\"的识别区域吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                        {
                            try
                            {
                                IsDrawing = true;
                                var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_RECTANGLE1);
                                IsDrawing = false;
                                if (!isClosing)
                                {
                                    var region = roi.getRegion();

                                    CameraAppendHObject0 = null;
                                    CameraGCStyle0 = new Tuple<string, object>("Color", "yellow");
                                    CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                                    CameraAppendHObject0 = region;

                                    HOperatorSet.RegionFeatures(region, "row1", out var row1);
                                    HOperatorSet.RegionFeatures(region, "column1", out var column1);
                                    HOperatorSet.RegionFeatures(region, "row2", out var row2);
                                    HOperatorSet.RegionFeatures(region, "column2", out var column2);

                                    visionPcs.Rec1Row1 = Math.Round(row1.D, 0);
                                    visionPcs.Rec1Column1 = Math.Round(column1.D, 0);
                                    visionPcs.Rec1Row2 = Math.Round(row2.D, 0);
                                    visionPcs.Rec1Column2 = Math.Round(column2.D, 0);

                                    mdb.SaveChanges();
                                }
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                    }
                }
            }
        }       
        async void ExecuteCameraOperateCommand(object obj)
        {
            if (obj is string str)
            {
                switch (str)
                {
                    case "测试":
                        {
                            IsBusy = true;
                            try
                            {
                                string calibfilepath1 = "Camera\\Calib\\Left";
                                string calibfilepath2 = "Camera\\Calib\\Right";

                                HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, calibfilepath1, "CalibHomMat2D.tup"), out var CalibHomMat2D1);
                                HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, calibfilepath2, "CalibHomMat2D.tup"), out var CalibHomMat2D2);

                                CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");

                                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                var _points = mdb.XYZRPoints.Where(p => p.Hand == handIndex).OrderBy(p => p.PcsOrder);
                                if (_points.Any())
                                {
                                    var _list = _points.ToList();
                                    foreach (var p in _list)
                                    {
                                        if (isClosing)
                                        {
                                            break;
                                        }
                                        var visionPcs = mdb.VisionPoints.FirstOrDefault(v => v.Hand == handIndex && v.PcsOrder == p.PcsOrder);
                                        if (visionPcs != null)
                                        {
                                            var flyimg = gTSCard.ImageList.FirstOrDefault(fly => fly.Track == visionPcs.Track && fly.Kind == visionPcs.ImageKind && fly.ImagePcsOrder == visionPcs.ImagePcsOrder && fly.CameraHand == visionPcs.CameraHand);
                                            if (flyimg != null)
                                            {
                                                HOperatorSet.CropPart(flyimg.MImage, out var imagePart, visionPcs.Rec1Row1, visionPcs.Rec1Column1, visionPcs.Rec1Column2 - visionPcs.Rec1Column1, visionPcs.Rec1Row2 - visionPcs.Rec1Row1);

                                                HTuple r_row = new HTuple(0), r_column = new HTuple(0), r_angle = new HTuple(0), result = new HTuple(0);
                                                VisionAction(visionPcs.ScriptFileName, imagePart, visionPcs.ModelKind, out r_row, out r_column, out r_angle, out result);

                                                CameraIamge0 = new HImage(imagePart);

                                                if (result.I == 1 && r_row.TupleLength() > 0 && r_column.TupleLength() > 0 && r_angle.TupleLength() > 0)
                                                {
                                                    HOperatorSet.GenCrossContourXld(out var cross1, r_row, r_column, 24, 0);
                                                    CameraGCStyle0 = new Tuple<string, object>("Color", "red");
                                                    CameraAppendHObject0 = cross1;

                                                    HOperatorSet.VectorAngleToRigid(visionPcs.ST_X, visionPcs.ST_Y, visionPcs.ST_Angle, r_row, r_column, r_angle, out var homMat2d);

                                                    HOperatorSet.AffineTransPoint2d(homMat2d, visionPcs.Target_X, visionPcs.Target_Y, out var trow1, out var tcolumn1);
                                                    HOperatorSet.GenCrossContourXld(out var cross0, trow1, tcolumn1, 24, r_angle - visionPcs.ST_Angle);
                                                    CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                                                    CameraAppendHObject0 = cross0;

                                                    var calibPoint = visionPcs.CameraHand == 0 ? systemParam.LeftCameraCalib : systemParam.RightCameraCalib;
                                                    var flypoint = mdb.FlyGrabPoints.FirstOrDefault(fly => fly.Hand == visionPcs.CameraHand && fly.Kind == visionPcs.ImageKind && fly.Track == visionPcs.Track && fly.PcsOrder == visionPcs.ImagePcsOrder);
                                                    if (flypoint != null)
                                                    {
                                                        HTuple _calc_qx, _calc_qy;
                                                        if (visionPcs.CameraHand == 0)
                                                        {
                                                            HOperatorSet.AffineTransPoint2d(CalibHomMat2D1, visionPcs.Rec1Row1 + trow1, visionPcs.Rec1Column1 + tcolumn1, out _calc_qx, out _calc_qy);
                                                        }
                                                        else
                                                        {
                                                            HOperatorSet.AffineTransPoint2d(CalibHomMat2D2, visionPcs.Rec1Row1 + trow1, visionPcs.Rec1Column1 + tcolumn1, out _calc_qx, out _calc_qy);
                                                        }
 
                                                        var calc_qx1 = _calc_qx + flypoint.X - calibPoint.X;
                                                        var calc_qy1 = _calc_qy + flypoint.Y - calibPoint.Y;
                                                        CameraAppendHMessage0 = new HMsgEntry($"{p.Name}: \nΔX:{(p.X - calc_qx1.D) * -1:f3}mm\nΔY:{(p.Y - calc_qy1.D) * -1:f3}mm\nΔR:{((visionPcs.ST_Angle - r_angle) * -1).TupleDeg().D:f2}°", 10, 10, _Size: 16, _coordSystem: "window");                                                 
                                                    }
                                                }
                                                else
                                                {
                                                    var regionrow = (visionPcs.Rec1Row2 - visionPcs.Rec1Row1) / 2;
                                                    var regioncolumn = (visionPcs.Rec1Column2 - visionPcs.Rec1Column1) / 2;
                                                    CameraAppendHMessage0 = new HMsgEntry($"{p.Name}: NG", 10, 10, _genParamName: new HTuple().TupleConcat("box_color"), _genParamValue: new HTuple().TupleConcat("red"),
                                                        _color: "white", _Size: 22, _coordSystem: "window");
                                                }
                                                await Task.Delay(1000);
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                            IsBusy = false;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        #endregion
        #region 导航
        public override void OnDialogClosed()
        {
            
            if (source0 != null)
            {
                source0.Cancel();
            }
            if (source1 != null)
            {
                source1.Cancel();
            }
            IHIKCameraService cameraService = handIndex == 0 ? leftCamera : rightCamera;
            cameraService.StopGrabe();
            //if (isModify)
            //{
            //    aggregator.SendMessage("ReloadCameraParam", "Run");
            //}
            isClosing = true;
            if (IsDrawing)
            {
                MFunc.HIOCancelDraw();
            }
        }
        public override void OnDialogOpened(IDialogParameters parameters)
        {
            LoadParam();
            string scriptname = string.Empty;
            pointId = parameters.GetValue<int>("PointId");
            try
            {
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var point = mdb.XYZRPoints.FirstOrDefault(point => point.Id == pointId);
                if (point != null)
                {
                    CameraHand = handIndex = point.Hand;

                    switch (handIndex)
                    {
                        case 0:
                            Title = $"左相机-算法:{point.Name}";
                            handDir = "Left";
                            break;
                        case 1:
                            Title = $"右相机-算法:{point.Name}";
                            handDir = "Right";
                            break;
                        default:
                            break;
                    }
                    var vision = mdb.VisionPoints.FirstOrDefault(vi => vi.Hand == point.Hand && vi.PcsOrder == point.PcsOrder);
                    if (vision != null)
                    {
                        scriptname = vision.ScriptFileName;
                        ModelKind = vision.ModelKind;
                        FlyTrack = vision.Track;
                        ChangeImagePcsOrderList(vision.Hand, vision.Track, vision.ImageKind);
                        ImagePcsOrderSelectedIndex = vision.ImagePcsOrder;
                        IsFlyGrab = vision.ImageKind != 0;
                        LoadImage(vision.Track, vision.ImageKind, vision.ImagePcsOrder);
                        if (CameraIamge0 != null)
                        {
                            HOperatorSet.GenRectangle1(out var rec, vision.Rec1Row1, vision.Rec1Column1, vision.Rec1Row2, vision.Rec1Column2);
                          
                            Task.Run(() =>
                            {
                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                {
                                    CameraGCStyle0 = new Tuple<string, object>("Color", "magenta");
                                    CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                                    CameraAppendHObject0 = rec;
                                }));
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            try
            {
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                
                
                var _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "XYJogSpeed");
                if (_mParam != null)
                {
                    mxYJogSpeed = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZJogSpeed");
                if (_mParam != null)
                {
                    mzJogSpeed = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZSafePos" && m.Hand == 0);
                if (_mParam != null)
                {
                    mz1SafePos = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZSafePos" && m.Hand == 1);
                if (_mParam != null)
                {
                    mz2SafePos = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "CameraExposureTime" && m.Hand == handIndex);
                if (_mParam != null)
                {
                    CameraExposureTime = double.Parse(_mParam.Value);
                }

                int selectIndex = -1;
                var programs = mdb.VisionPrograms.Where(m => m.Id > 0);
                if (programs.Any())
                {
                    int _index = 0;
                    programs.ToList().ForEach(program => {
                        ScriptList.Add(new VisionProgramDisp { 
                            Id = program.Id,
                            Name = program.Name
                        });
                        if (scriptname == $"{program.Id}_{program.Name}" )
                        {
                            selectIndex = _index;
                        }
                        _index++;
                    });
                }
                ScriptListSelectedIndex = selectIndex;

                ImageList.Clear();
                for (int i = 0; i < gTSCard.ImageList.Count; i++)
                {
                    ImageList.Add(i + 1);
                }

                var flyGrabPoints = mdb.FlyGrabPoints.Where(f => f.Hand == handIndex && f.Kind == 1);
                if (flyGrabPoints.Any())
                {
                    var maxTrack = flyGrabPoints.Max(f => f.Track);
                    for (int i = 0; i <= maxTrack; i++)
                    {
                        FlyTrackList.Add(i + 1);
                        FlyTrackList2.Add(new FlyTrackDisp
                        {
                            V1 = i + 1,
                            IsChecked = i == FlyTrack
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            LoadFlyPoint(0); LoadFixedPoint();
            
        }
        #endregion
        #region 构造函数
        public CameraVisionDialogViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            IsSaveToStandardShow = false;
            IsBusy = false;
           
            ImagePcsOrderList = new ObservableCollection<int>();
            drawROI = containerProvider.Resolve<DrawROI>();

            leftCamera = containerProvider.Resolve<IHIKCameraService>("LeftCamera");
            rightCamera = containerProvider.Resolve<IHIKCameraService>("RightCamera");
            gTSCard = containerProvider.Resolve<IGTSCardService>("GTSCard");
            aggregator.ResgiterMessage(arg =>
            {
                switch (arg.Message)
                {
                    case "GrabActionDone":
                        isGrabActionDone = true;
                        break;                    
                    default:
                        break;
                }
            }, "Run");
        }
        #endregion
        #region 功能函数
        void LoadParam()
        {
            try
            {
                //Json序列化，从文件读取
                string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Param.json"));
                systemParam = JsonConvert.DeserializeObject<Param>(jsonString);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }
        void LoadFixedPoint()
        {
            try
            {
                PointList3.Clear();
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == handIndex && f.Kind == 0).OrderBy(f => f.PcsOrder);
                if (flyPoints.Any())
                {
                    flyPoints.ToList().ForEach(f => {
                        PointList3.Add(new FlyPointDisp
                        {
                            Id = f.Id,
                            PcsOrder = f.PcsOrder,
                            X = f.X,
                            Y = f.Y,
                            Z = f.Z,
                            UseLight1 = f.UseLight1,
                            UseLight2 = f.UseLight2
                        });
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void LoadFlyPoint(int track)
        {
            try
            {
                PointList1.Clear(); PointList2.Clear(); 
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == handIndex && f.Kind == 1 && f.Track == track).OrderBy(f => f.PcsOrder);
                if (flyPoints.Any())
                {
                    flyPoints.ToList().ForEach(f => {
                        PointList1.Add(new FlyPointDisp
                        {
                            Id = f.Id,
                            PcsOrder = f.PcsOrder,
                            X = f.X,
                            Y = f.Y,
                            Z = f.Z
                        });
                    });
                }
                //ImagePcsOrderList.Clear();
                //for (int i = 0; i < PointList1.Count; i++)
                //{
                //    ImagePcsOrderList.Add(i);
                //}
                var flyPoints2 = mdb.FlyGrabPoints.Where(f => f.Hand == handIndex && f.Kind == 2 && f.Track == track).OrderBy(f => f.PcsOrder);
                if (flyPoints2.Any())
                {
                    flyPoints2.ToList().ForEach(f => {
                        PointList2.Add(new FlyPointDisp
                        {
                            Id = f.Id,
                            PcsOrder = f.PcsOrder,
                            X = f.X,
                            Y = f.Y,
                            Z = f.Z,
                            UseLight1 = f.UseLight1,
                            UseLight2 = f.UseLight2
                        });
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        void ChangeImagePcsOrderList(int hand,int track,int kind)
        {
            ImagePcsOrderList.Clear();
            using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
            var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == hand && f.Kind == kind && f.Track == track).OrderBy(f => f.PcsOrder);
            if (flyPoints.Any())
            {
                flyPoints.ToList().ForEach(p => {
                    ImagePcsOrderList.Add(p.PcsOrder);
                });
            }
        }
        private void LoadImage(int track,int kind,int _index)
        {
            var mimage1 = gTSCard.ImageList.FirstOrDefault(img => img.Track == track && img.Kind == kind && img.CameraHand == CameraHand && img.ImagePcsOrder == _index);
            if (mimage1 != null)
            {
                CameraIamge0 = new HImage(mimage1.MImage.CopyObj(1, -1));
            }
            else
            {
                CameraIamge0 = null;
            }
        }
        private void ContinueGrab(CancellationToken token)
        {
            IHIKCameraService cameraService = handIndex == 0 ? leftCamera : rightCamera;
            cameraService.ImageQueue.Clear();
            cameraService.SetTriggerMode(0);
            cameraService.SetExposureTime((float)CameraExposureTime);
            cameraService.StartGrabe();
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    cameraService.StopGrabe();
                    return;
                }
                HObject? hObj;
                if (cameraService.ImageQueue.TryPeek(out hObj))
                {
                    cameraService.ImageQueue.TryDequeue(out hObj);
                    CameraIamge0 = new HImage(hObj);
                }
                System.Threading.Thread.Sleep(1);
            }
        }
        void ScanGrabImageAction(CancellationToken token)
        {
            int stepnum = 0;
           
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    switch (stepnum)
                    {
                        case 0:
                            isGrabActionDone = false;
                            aggregator.SendMessage("GrabAction", "Run");
                            stepnum = 1;
                            break;
                        case 1:
                            if (isGrabActionDone)
                            {
                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                {
                                    ImageList.Clear();
                                    for (int i = 0; i < gTSCard.ImageList.Count; i++)
                                    {
                                        ImageList.Add(i + 1);
                                    }
                                }));
                             
                                return;
                            }
                            break;
                        default:
                            break;
                    }
                }
                catch { }
                System.Threading.Thread.Sleep(100);
            }
        }
        private void JumpAction(CancellationToken token, double tartgetX, double tartgetY, double tartgetZ, AxisParm axisX, AxisParm axisY, AxisParm axisZ, double ZSafe)
        {
            try
            {
                int stepnum = 0;
                while (true)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    switch (stepnum)
                    {
                        case 0://Z运动到安全位
                            {
                                GTSCard.AxisPosMove(ref axisZ, ZSafe, mzJogSpeed);
                                stepnum = 1;
                            }
                            break;
                        case 1:
                            if (GTSCard.AxisPosMoveCheckDone(axisZ))
                            {
                                stepnum = 2;
                            }
                            break;
                        case 2:
                            {
                                GTSCard.AxisPosMove(ref axisX, tartgetX, mxYJogSpeed);
                                GTSCard.AxisPosMove(ref axisY, tartgetY, mxYJogSpeed);
                                stepnum = 3;
                            }
                            break;
                        case 3:
                            if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY))
                            {
                                stepnum = 4;
                            }
                            break;
                        case 4:
                            {
                                GTSCard.AxisPosMove(ref axisZ, tartgetZ, mzJogSpeed);
                                stepnum = 5;
                            }
                            break;
                        case 5:
                            if (GTSCard.AxisPosMoveCheckDone(axisZ))
                            {
                                return;
                            }
                            break;
                        default:
                            break;
                    }
                    System.Threading.Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Debug.WriteLine(ex.Message);
            }
        }
        private void GoAction(CancellationToken token, double tartgetX, double tartgetY, double tartgetZ, AxisParm axisX, AxisParm axisY, AxisParm axisZ)
        {
            try
            {
                int stepnum = 0;
                while (true)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    switch (stepnum)
                    {
                        case 0:
                            {
                                GTSCard.AxisPosMove(ref axisX, tartgetX, mxYJogSpeed);
                                GTSCard.AxisPosMove(ref axisY, tartgetY, mxYJogSpeed);
                                GTSCard.AxisPosMove(ref axisZ, tartgetZ, mzJogSpeed);
                                stepnum = 1;
                            }
                            break;
                        case 1:
                            if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY) &&
                                GTSCard.AxisPosMoveCheckDone(axisZ))
                            {
                                return;
                            }
                            break;
                        default:
                            break;
                    }
                    System.Threading.Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Debug.WriteLine(ex.Message);
            }

        }
        private void VisionAction(string procedureName, HObject img, HTuple dir, out HTuple row,
            out HTuple column, out HTuple angle, out HTuple result)
        {
            result = new HTuple(0);
            try
            {
                string[] strs = procedureName.Split("_");
                int id = int.Parse(strs[0]);
                HOperatorSet.RotateImage(img, out var ho_ImageRotate, (90 * dir) * -1, "constant");
                HOperatorSet.GetImageSize(ho_ImageRotate, out var hv_Width, out var hv_Height);
                HTuple hv_row = new HTuple(0), hv_column = new HTuple(0), hv_angle = new HTuple(0), hv_score = new HTuple(0), v1 = new HTuple(0), v2 = new HTuple(0);
                HObject eImage = ho_ImageRotate;
                HObject ngRegion, SelectedRegion;
                HOperatorSet.GenEmptyObj(out ngRegion);
                HOperatorSet.GenEmptyObj(out SelectedRegion);
                bool r1 = true;
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var projects = mdb.VisionProjects.Where(pro => pro.ProgramId == id).OrderBy(pro => pro.PcsOrder);
                if (projects.Any())
                {                    
                    var mprojects = projects.ToList();
                    foreach (var project in mprojects)
                    {
                        if (!r1)
                        {
                            break;
                        }
                        var _function = mdb.VisionFunctions.FirstOrDefault(func => func.Id == project.FunctionId);
                        if (_function != null)
                        {
                            r1 = MFunc.FunDictionary[_function.Name].Run(ref eImage, project.Parameter, ref hv_row, ref hv_column, ref hv_angle, ref hv_score, ref ngRegion, ref SelectedRegion,ref v1, ref v2);                            
                        }
                        else
                        {
                            r1 = false;
                        }
                    }
                    
                }
                if (r1)
                {
                    result = new HTuple(1);
                    row = hv_row;
                    column = hv_column;
                    angle = hv_angle;
                    switch (dir.I)
                    {
                        case 1://90°
                            {
                                var box = row;
                                row = hv_Width - 1 - column;
                                column = box;
                            }
                            break;
                        case 2://180°
                            {
                                var box1 = row;
                                var box2 = column;
                                row = box1 * -1 + hv_Height - 1;
                                column = box2 * -1 + hv_Width - 1;
                            }
                            break;
                        case 3://270°
                            {
                                var box1 = hv_Width - 1 - column;
                                var box2 = row;
                                row = box1 * -1 + hv_Width - 1;
                                column = box2 * -1 + hv_Height - 1;
                            }
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    result = new HTuple(0);
                    row = new HTuple(0);
                    column = new HTuple(0);
                    angle = new HTuple(0);
                }
                eImage.Dispose();
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                result = new HTuple(0);
                row = new HTuple(0);
                column = new HTuple(0);
                angle = new HTuple(0);
            }

        }
        #endregion
    }
    public class PcsItem
    {
        public int Id { get; set; }
        public int PcsOrder { get; set; }
        public string Name { get; set; }
    }
    public class FlyPointDisp : DispBase
    {
        public int Id { get; set; }
        public int PcsOrder { get; set; }
        private double x;

        public double X
        {
            get { return x; }
            set
            {
                if (x != value)
                {
                    x = value;
                    OnPropertyChanged();
                }
            }
        }
        private double y;

        public double Y
        {
            get { return y; }
            set
            {
                if (y != value)
                {
                    y = value;
                    OnPropertyChanged();
                }
            }
        }
        private double z;

        public double Z
        {
            get { return z; }
            set
            {
                if (z != value)
                {
                    z = value;
                    OnPropertyChanged();
                }
            }
        }
        private bool useLight1;

        public bool UseLight1
        {
            get { return useLight1; }
            set
            {
                if (useLight1 != value)
                {
                    useLight1 = value;
                    OnPropertyChanged();
                }
            }
        }
        private bool useLight2;

        public bool UseLight2
        {
            get { return useLight2; }
            set
            {
                if (useLight2 != value)
                {
                    useLight2 = value;
                    OnPropertyChanged();
                }
            }
        }
    }
    public class FlyTrackDisp : DispBase
    {
        public int V1 { get; set; }
        private bool isChecked;

        public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                if (isChecked != value)
                {
                    isChecked = value;
                    OnPropertyChanged();
                }
            }
        }

    }
}
